<template>
  <div :data-info="`${hasCallShow}-${layerNameKey}`">
    <!-- {{hasCallShow}} -->
    <!-- 入口文件 -->
    <VFormRender
      :form-json="formJson"
      :form-data="formData"
      :parent-api="parentApi"
      :option-data="optionData"
      ref="vFormRef"
    />
    <!-- 弹窗配置 -->
    <component
      v-if="layerNameKey != null"
      :is="layerNameKey"
      :visible="hasCallShow"
      :info="waitingScreenMsgWinData"
      :check-list="waitingScreenMsgWinData.checkList"
    />
  </div>
</template>

<script>
import VFormRender from "@c/public/form-render/index.vue";
import { setRem2 } from "@/utils/rem.js";
import { AndroidSDK } from "@/sdk/AndroidSdkService";
import { resetLongToStr } from "@/utils/biz/common/BizUtils";
import { SubjectUtil } from "@/utils/observer/SubjectUtil";
import { SetDateObserverBiz } from "@/utils/biz/common/SetDateObserverBiz";
import LayerComps from "@/components/public/layer/scenes";
import { WaitPatientCommonObserverBiz } from "@/utils/biz/waiting/WaitPatientCommonObserverBiz";
import { WaitPatientLogObserverBiz } from "@/utils/biz/waiting/WaitPatientLogObserverBiz";
import { WaitPatientObserverBiz } from "@/utils/biz/waiting/WaitPatientObserverBiz";
import { WaitPatientAloneObserverBiz } from "@/utils/biz/waiting/WaitPatientAloneObserverBiz";
import { WaitOverObserverBiz } from "@/utils/biz/waiting/WaitOverObserverBiz";
import { WaitEmbedCallingPatientRecordsObserverBiz } from "@/utils/biz/waiting/WaitEmbedCallingPatientRecordsObserverBiz";
import { UserCommitApi } from "@/api/user_common";
import { CallObserverBiz } from "@/utils/biz/waiting/CallObserverBiz";

export default {
  name: "WaitingScreen",

  props: {
    formJson: {
      widgetList: [],
      formConfig: {
        devType: true,
      },
    },
    formConfig: {},
    formData: Object,
    templateInfo: {},
    // 0表示门诊 1 第三方 2 其他
    apiType: {
      type: Number,
      default: 0,
    },
    optionData: {},
  },

  components: {
    VFormRender,
    ...LayerComps,
  },

  data() {
    return {
      parentApi: this.createParentOptions(),
      deviceInfo: null,
      // 组件缓存
      modelMap: {},
      // 缓存
      commonJsonMap: {},
      // 结构
      eventBus: null,
      data: [],
      // 弹窗组件名称
      layerNameKey: "call-patient",
      hasCallShow: false,
      hasCallShowArt: false,
      // 是否动态变更顶部科室名称
      trendsKey: false,
      contentKey: "deptName",
      // 呼叫记录
      waitingScreenPatientLog: [],
      // 是否查询在线
      recordsLine: false,
      // 当前屏 全部的医生ID
      currentWorkerList: [],
      /**
       * 候诊屏数据缓存
       */
      waitingScreenWaitingData: {
        // 当前屏等候患者列表
        currentList: [],
        // 候诊屏 -- 列表模拟数据开关
        mockOpen: true,
        // 分页数量
        pageSize: 10,
        // 切屏时间
        switchSeconds: 10,
        // 数据显示规则 1:医生，2 号别
        queryRule: 1,
        // 弹窗是否需要原始数据
        layerOriginalDate: false,
        // 内嵌呼叫患者配置
        embedCallingPatientConfig: {
          // 分页数量
          pageSize: 10,
          // 第几页
          pageNum: 1,
        },
        // 是否截取数据
        waitPatientSlice: false,

        // 是否查询正在就诊  数据显示规则 1:否 ，2 是
        showCurrentPatient: "2",
        // 是否查询公共队列  数据显示规则 1:否 ，2 是
        showAllWaitPatient: "2",
        // 候诊屏绑定号别 增加是否展示诊室开关  数据显示规则 1:否 ，2 是
        showRoomName: "1",
        // 是否显示挂起数据
        containHangupData: false,
      },
      /**
       * 候诊屏 弹窗
       */
      waitingScreenMsgWinData: {
        deptName: "",
        treatmentRoomName: "",
        workStationName: "",
        registerObjName: "",
        treatingAlert: true, // 是否显示就诊弹窗
        waitingAlert: true, // 是否显示候诊弹窗
        currPatient: [],
        waitPatient: [],
        treatingVoiceContentConfig: [],
        waitingVoiceContent: "",
        checkList: [1, 3],
        // 号别显示名称
        registerObjNameKey: "registerObjName",

        current: {
          content: "就诊",
        },
        waiting: {
          content: "候诊",
        },
        popupBackground: "",
        overlayBackground: "",
        data: {},
      },
      // 注册标识
      msgRegisterMark: "",
    };
  },

  mounted() {
    this.setRem();
    // 初始化
    this.init();
  },

  methods: {
    // 安卓报错信息的写入
    handleException(funcName, errType, errMsg) {
      AndroidSDK.writeLog(`${funcName}--${errType}-->${errMsg}`);
    },

    // 安卓正常写入日志
    handleWriteLog(funcName, msgContent) {
      AndroidSDK.writeLog(`${funcName}---->${msgContent}`);
    },

    /**
     * 安卓调用
     * @param obj
     */
    sdkServices(obj) {
      this.handleWriteLog("sdkServices", JSON.stringify(obj));
      try {
        if (obj.bizType && obj.bizType !== "") {
          switch (obj.bizType) {
            case "getDeviceInfoCallBack":
              this.deviceInfo = JSON.parse(resetLongToStr(obj.msgContent));
              this.initAfterGetDeviceInfo();
              break;
            case "webPing":
              AndroidSDK.androidPong();
              break;
            case "setDate":
              this.setDate(obj.msgContent);
              this.eventBus.$emit(obj.bizType, obj.msgContent);
              break;
            default:
              // 监听设置
              this.eventBus.$emit(obj.bizType, obj.msgContent);
          }
        } else {
          this.handleException("sdkServices", "数据错误", JSON.stringify(obj));
        }
      } catch (e) {
        this.handleException("sdkServices", "解析错误", JSON.stringify(obj));
      }
    },

    /**
     * 安卓调用
     * @param obj
     */
    sdkBizServices(obj) {
      this.handleWriteLog("sdkBizServices", JSON.stringify(obj));
      try {
        if (obj.bizType && obj.bizType !== "") {
          this.eventBus.$emit(obj.bizType, obj.msgContent);
        } else {
          this.handleException(
            "sdkBizServices",
            "数据错误",
            JSON.stringify(obj)
          );
        }
      } catch (e) {
        this.handleException("sdkBizServices", "解析错误", JSON.stringify(obj));
      }
    },

    /**
     * 初始化逻辑
     */
    init() {
      // 数据挂载
      parent.window.webSDKServices = this.sdkServices;
      parent.window.webSDKBizServices = this.sdkBizServices;
      AndroidSDK.androidPong();
      // 遍历数据 将模板数据存储到Map缓存中
      this.formJson.widgetList.forEach((item) => {
        this.modelMap[item.categoryType] = item;
      });
      // 设置接口中需要用的参数
      this.setParams();
      // 主题消息 Subject
      this.eventBus = new SubjectUtil();

      //获取终端信息
      AndroidSDK.getDeviceInfo();

      // 给安卓发消息
      AndroidSDK.queueSwitchAction({
        pageSize: this.waitingScreenWaitingData.pageSize,
        switchSeconds: this.waitingScreenWaitingData.switchSeconds,
        queryRule: this.waitingScreenWaitingData.queryRule,
        // 0表示门诊 1 第三方 2 其他
        dataSource: this.apiType,
      });
    },
    /**
     * 初始化 模板参数
     */
    setParams() {
      // 加载主屏逻辑
      let mainInfo = this.modelMap["waiting-patient"];
      if (mainInfo) {
        let configObj = mainInfo.options[mainInfo.options.config];
        this.waitingScreenWaitingData.pageSize =
          (configObj.showRowNums || 10) * (configObj.multiple || 1) || 5;
        this.waitingScreenWaitingData.switchSeconds =
          configObj.switchTime || 10;
        // 是否查询正在就诊  数据显示规则 1:否 ，2 是
        this.waitingScreenWaitingData.showCurrentPatient =
          configObj.showCurrentPatient || "2";
        // 是否查询公共队列  数据显示规则 1:否 ，2 是
        this.waitingScreenWaitingData.showAllWaitPatient =
          configObj.waitPatientType || "2";
        // 候诊屏绑定号别 增加是否展示诊室开关  数据显示规则 1:否 ，2 是
        this.waitingScreenWaitingData.showRoomName =
          configObj.showRoomName || "1";
        // 是否查询挂起数据
        this.waitingScreenWaitingData.containHangupData =
          configObj.containHangupData === true;
        // 数据查询类型
        if (
          configObj.queryRule &&
          Array.isArray(configObj.queryRule) &&
          configObj.queryRule.length > 0
        ) {
          this.waitingScreenWaitingData.queryRule = configObj.queryRule[0] || 1;
        }
        // 弹窗号别配置
        this.waitingScreenMsgWinData.checkList = configObj.checkList || [1, 3];
        // 模板中配置的号别KEY
        this.waitingScreenMsgWinData.registerObjNameKey =
          configObj.registerObjNameKey || "registerObjName";
        // 模板中配置叫号器名字
        this.waitingScreenMsgWinData.workStationName =
          configObj?.terminalName || configObj?.workerName;
        // 设置弹窗名称
        if (configObj.layerInfo && configObj.layerInfo.current) {
          this.waitingScreenMsgWinData.current = configObj.layerInfo
            .current || { content: "就诊" };
          // 颜色
          this.waitingScreenMsgWinData.popupBackground =
            configObj.layerInfo.current.popupBackground || "";
          // 透明度
          this.waitingScreenMsgWinData.overlayBackground =
            configObj.layerInfo.current.overlayBackground || "";
        }
        if (configObj.layerInfo && configObj.layerInfo.waiting) {
          this.waitingScreenMsgWinData.waiting = configObj.layerInfo
            .waiting || { content: "候诊" };
        }
        // 顶部科室 是否动态切换
        this.trendsKey = configObj.trendsKey || false;
        this.contentKey = configObj.contentKey || "deptName";
        // 调用哪个弹窗
        this.layerNameKey = configObj.layerNameKey || "call-patient";
        // 弹窗是否用原始数据 -- 定制
        this.waitingScreenWaitingData.layerOriginalDate =
          configObj.layerOriginalDate || false;
        // 内置呼叫记录
        this.waitingScreenWaitingData.embedCallingPatientConfig.pageSize =
          configObj.recordsNumber || 5;
        // 是否在线
        this.recordsLine = configObj.recordsLine || false;
        // 特制消息标识
        this.msgRegisterMark = configObj.msgRegisterMark || "";
      }
    },
    /**
     * 获取设备信息后初始化
     */
    initAfterGetDeviceInfo() {
      // 特制消息清理+注册
      this.registerMsg();
      // 加载类
      if (this.modelMap["waiting-patient"]) {
        let tempData = this.modelMap["waiting-patient"];
        // 候诊屏类型是只查询呼叫记录的场景
        if (tempData.screenDataType.indexOf("patientLog") > -1) {
          let emp = new WaitPatientLogObserverBiz(
            this,
            this.deviceInfo,
            tempData
          );
          this.eventBus.addObserver(emp);
          emp.init();
        } else {
          // 内置通用候诊屏处理逻辑
          let emp = new WaitPatientObserverBiz(this, this.deviceInfo, tempData);
          this.eventBus.addObserver(emp);
          emp.init();
        }

        // 内置呼叫记录
        if (
          tempData?.screenDataType.indexOf("embedCallingPatientRecords") > -1
        ) {
          let emp = new WaitEmbedCallingPatientRecordsObserverBiz(
            this,
            this.deviceInfo,
            tempData
          );
          this.eventBus.addObserver(emp);
          emp.init();
        }
        // 设置弹窗 -- 儿童弹窗
        if (tempData?.screenDataType.indexOf("waitingArt") > -1) {
          this.layerNameKey = "call-patient-art";
        }

        // 设置过号数据
        if (tempData?.screenDataType.indexOf("pass") > -1) {
          let emp = new WaitOverObserverBiz(this, this.deviceInfo, tempData);
          this.eventBus.addObserver(emp);
          emp.init();
        }
      }

      // 加载类 通用-等候
      if (this.modelMap["wait-patient-common"]) {
        let tempData = this.modelMap["wait-patient-common"];
        let emp = new WaitPatientCommonObserverBiz(
          this,
          this.deviceInfo,
          tempData
        );
        this.eventBus.addObserver(emp);
        emp.init();
      }

      // 加载类
      if (this.modelMap["waiting-patient-alone"]) {
        let tempData = this.modelMap["waiting-patient-alone"];
        let emp = new WaitPatientAloneObserverBiz(
          this,
          this.deviceInfo,
          tempData
        );
        this.eventBus.addObserver(emp);
        emp.init();
      }
      // todo 叫号消息拦截
      if (this.modelMap["call-common"]) {
        // 头部时间 - 观察者
        let emp = new CallObserverBiz(
          this,
          this.deviceInfo,
          this.modelMap["call-common"]
        );
        this.eventBus.addObserver(emp);
      }
      // 头部时间
      if (this.modelMap["header"]) {
        // 头部时间 - 观察者
        let emp = new SetDateObserverBiz(
          this,
          this.deviceInfo,
          this.modelMap["header"]
        );
        this.eventBus.addObserver(emp);
      }

      // 通用过号组件
      if (this.modelMap["pass-patient-common"]) {
        let tempData = this.modelMap["pass-patient-common"];
        // 过号 - 观察者
        let emp = new WaitOverObserverBiz(this, this.deviceInfo, tempData);
        this.eventBus.addObserver(emp);
        emp.init();
      }

      // 获取多媒体
      this.getVideoMedias();
      this.sendDeviceInfo(this.deviceInfo);
    },

    /**
     * 消息注册
     */
    async registerMsg() {
      // 特制消息存在才会注册
      try {
        // 注册消息
        const { code, data } = await UserCommitApi.bindTerminalBusinessFlag({
          terminalId: this.deviceInfo.screenId,
          terminalType: this.deviceInfo.screenType,
          businessFlag: this.msgRegisterMark,
        });
      } catch (e) {
        this.handleException(
          "sdkBizServices",
          "特制消息注册失败 -- registerMsg -- >",
          JSON.stringify(e.stack)
        );
      }
    },

    /**
     * 适配2k 4k
     */
    setRem() {
      const { resolution } = this.templateInfo;
      if (resolution) {
        // 重新计算尺寸
        setRem2(19.2, resolution.split("*")[0]);
        window.onresize = function () {
          setRem2(19.2, resolution.split("*")[0]);
        };
      }
    },

    createParentOptions() {
      return {
        self: this,
        executeParentMethod(key, data) {
          switch (key) {
            case "writeLog":
              // 内部组件调用 诙谐LOG 日志
              this.self.handleWriteLog(
                "sdkBizServices",
                "内部组件打印日志 -- >",
                data || ""
              );
              break;
            case "playVideoMedias":
              // 获取视频组件位置 给安卓
              this.self.playVideoMedias(data);
              break;
            case "callPatientInfo":
              break;
          }
        },
      };
    },
    /**
     * 获取多媒体
     * @param data
     */
    getVideoMedias(data) {
      try {
        let roomItem = this.modelMap["waiting-patient"];
        const formRef = this.$refs.vFormRef;
        if (formRef) {
          this.$refs.vFormRef.executeChildMethod(
            roomItem?.id,
            "getVideoMedias",
            data || {}
          );
        }
      } catch (e) {
        this.handleException(
          "sdkBizServices",
          "内部组件异常 -- getVideoMedias -- >",
          JSON.stringify(e.stack)
        );
      }
    },
    setDate(obj) {
      // 头部时间 - 观察者
      let empTime = new SetDateObserverBiz(
        this,
        this.deviceInfo,
        this.modelMap["waiting-patient"]
      );
      this.eventBus.addObserver(empTime);
      try {
        let mainItem = this.modelMap["waiting-patient"];
        const formRef = this.$refs.vFormRef;
        if (formRef) {
          this.$refs.vFormRef.executeChildMethod(mainItem?.id, "setDate", obj);
        }
      } catch (e) {
        this.handleException(
          "sdkBizServices",
          "内部组件异常 -- setDate -- >",
          JSON.stringify(e.stack)
        );
      }
    },
    sendDeviceInfo(data) {
      try {
        let roomItem = this.modelMap["waiting-patient"];
        const formRef = this.$refs.vFormRef;
        if (formRef) {
          this.$refs.vFormRef.executeChildMethod(
            roomItem?.id,
            "sendDeviceInfo",
            data || {}
          );
        }
      } catch (e) {
        this.handleException(
          "sdkBizServices",
          "内部组件异常 -- sendDeviceInfo -- >",
          JSON.stringify(e.stack)
        );
      }
    },

    /**
     * 获取 多媒体
     * @param obj
     */
    playVideoMedias(obj) {
      try {
        const { positionInfo, video } = obj;
        const { left, top, width, height } = positionInfo;
        const resources = [];
        video.forEach((item) => {
          resources.push({
            url: item.url,
          });
        });
        AndroidSDK.playVideoMedias({
          x: left,
          y: top,
          width: width,
          height: height,
          type: "2",
          resources,
        });
      } catch (e) {
        this.handleException(
          "sdkBizServices",
          "获取多媒体数据解析失败",
          JSON.stringify(e.stack)
        );
      }
    },
  },
};
</script>
